package clickstreamhack;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.clickstream.Clickstream;
import com.opensymphony.clickstream.ClickstreamRequest;

@SuppressWarnings({"unchecked", "serial"})
public class HackedClickstream extends Clickstream {

	private static final long serialVersionUID = -5034562898851503044L;
	
	private static Log logger = LogFactory.getLog(HackedClickstream.class);
	
	private final Clickstream stream;

	public HackedClickstream(Clickstream stream) {
		this.stream = stream;
		hackStreams();
	}
	private void hackStreams() {
		try {
			Field streamsField = Clickstream.class.getDeclaredField("clickstream");
			streamsField.setAccessible(true);
			streamsField.set(stream, hackedStreams((List<ClickstreamRequest>) streamsField.get(stream)));			
		} catch (Exception e) {
			logger.error("Unable to hack ", e);
		}
	}

	private List<ClickstreamRequest> hackedStreams(List<ClickstreamRequest> object) {
		return Collections.synchronizedList(new ArrayList<ClickstreamRequest>() {
			@Override
			public boolean add(ClickstreamRequest request) {
				return super.add(new HackedClickstreamRequest(request));
			}
		});
	}

	public void addRequest(HttpServletRequest request) {
		stream.addRequest(request);
	}

	public boolean equals(Object obj) {
		return stream.equals(obj);
	}

	public Object getAttribute(String name) {
		return stream.getAttribute(name);
	}

	public Set<String> getAttributeNames() {
		return stream.getAttributeNames();
	}

	public String getHostname() {
		return stream.getHostname();
	}

	public String getInitialReferrer() {
		return stream.getInitialReferrer();
	}

	public Date getLastRequest() {
		return stream.getLastRequest();
	}

	public HttpSession getSession() {
		return stream.getSession();
	}

	public Date getStart() {
		return stream.getStart();
	}

	public List<ClickstreamRequest> getStream() {
		return stream.getStream();
	}

	public int hashCode() {
		return stream.hashCode();
	}

	public boolean isBot() {
		return stream.isBot();
	}

	public void setAttribute(String name, Object value) {
		stream.setAttribute(name, value);
	}


	
	
}
